package com.sduept.nwld.dataserver.controller.fault;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.event.SelectEvent;
import org.primefaces.event.UnselectEvent;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;
import org.primefaces.model.UploadedFile;

import com.sduept.bigdata.fault.entity.FaultRecord;
import com.sduept.bigdata.fault.manager.FaultRecordQueryManager;
import com.sduept.bigdata.fault.manager.FaultSourcePersistManager;
import com.sduept.bigdata.fault.manager.WaveFileAssistManager;
import com.sduept.cim.model.core.Equipment;
import com.sduept.cim.model.extend.AbstractWaveFile;
import com.sduept.cim.model.protection.ProtectionEquipment;
import com.sduept.cim.model.protection.WaveEquipment;
import com.sduept.nwld.wave.manager.CfgFileValidateUtil;
import com.sduept.bigdata.web.jsf.controller.AbstractController;
import org.springframework.beans.factory.annotation.Autowired;

@Named
@ViewScoped
public class WaveFileController extends AbstractController{

	private static final long serialVersionUID = -7231852485919627671L;

	@Autowired
	private FaultRecordQueryManager recordQueryManager;
	@Autowired
	private WaveFileAssistManager wfam;
	@Autowired
	private FaultSourcePersistManager fspm;

	/**
	 * 录波文件上传和下载
	 */
	public static final String FILE_FORMAT_CFG = "cfg";
	public static final String FILE_FORMAT_DAT = "dat";

	private String faultId = null;
	private FaultRecord fault = null;
	private HashMap<String,List<AbstractWaveFile>> waveFiles = new HashMap<String,List<AbstractWaveFile>>();
	private HashMap<String,List<Equipment>> waveEquipments = new HashMap<String,List<Equipment>>();

	private boolean showRelatedEquipment = true;
	private Equipment selectedWaveEquipment;
	private StreamedContent downloadFile;
	private Map<String, byte[]> uploadFileMap = new HashMap<>();
	private String uploadMsg="";

	@PostConstruct
	public void init() {
		if(faultId == null) {
			faultId = getParameter("faultId");
		}
		if(StringUtils.isNotEmpty(faultId)){
			fault = recordQueryManager.findById(faultId);
		}
		if(fault!= null) {
			generateWaveFileList();
			generateWaveEquipmentList();
		}
	}

	public void initByFault(FaultRecord faultItem){
		fault=faultItem;
		faultId=fault.getId();
		generateWaveFileList();
		generateWaveEquipmentList();
	}

	public void refresh() {
		fault = recordQueryManager.findById(faultId);
		generateWaveFileList();
		generateWaveEquipmentList();

	}

	public void generateWaveFileList() {
		if(StringUtils.isNotBlank(fault.getStationId())) {
			List<AbstractWaveFile> files = wfam.findWaveFileList(fault, fault.getStationId());
			waveFiles.put(fault.getStationId(), files);
		}
		if(StringUtils.isNotBlank(fault.getStationId2())) {
			List<AbstractWaveFile> files = wfam.findWaveFileList(fault, fault.getStationId2());
			waveFiles.put(fault.getStationId2(), files);
		}
	}

	public void generateWaveEquipmentList() {
		waveEquipments.clear();
		if(showRelatedEquipment) {
			if(StringUtils.isNotEmpty(fault.getStationId())){
				waveEquipments.put(fault.getStationId(), wfam.findWaveEquipmentList(fault, fault.getStationId()));
			}
			if(StringUtils.isNotEmpty(fault.getStationId())){
				waveEquipments.put(fault.getStationId2(), wfam.findWaveEquipmentList(fault, fault.getStationId2()));
			}
		}else {
			if(StringUtils.isNotEmpty(fault.getStationId())){
				waveEquipments.put(fault.getStationId(), wfam.findWaveEquipmentFullList(fault, fault.getStationId()));
			}
			if(StringUtils.isNotEmpty(fault.getStationId())){
				waveEquipments.put(fault.getStationId2(), wfam.findWaveEquipmentFullList(fault, fault.getStationId2()));
			}
		}
	}

	public void changeWaveEquipmentList() {
		generateWaveEquipmentList();
		selectedWaveEquipment = null;
	}

	public List<Equipment> getCurrentWaveEquipmentList(String stationId){
		List<Equipment> result=new ArrayList<>();
		if(StringUtils.isNotEmpty(stationId)){
			return waveEquipments.get(stationId);
		}
		if(null!=fault){
			if(StringUtils.isNotEmpty(fault.getStationId())){
				result.addAll(waveEquipments.get(fault.getStationId()));
			}
			if(StringUtils.isNotEmpty(fault.getStationId2())){
				result.addAll(waveEquipments.get(fault.getStationId2()));
			}
		}
		return result;
	}

	public boolean btnAvailable(){
		return StringUtils.isNotEmpty(uploadMsg)?true:false;
	}

	public void resetUploadMsg(){
		uploadMsg="";
	}
	private void updateUploadMsg(UploadedFile uf){
		try {
			String str = IOUtils.toString(uf.getInputstream(), "gbk");
			if(selectedWaveEquipment instanceof WaveEquipment){
				uploadMsg = CfgFileValidateUtil.getValidateCfgMsg(str, fault,true);
			}else{
				uploadMsg = CfgFileValidateUtil.getValidateCfgMsg(str, fault,false);
			}
			if(StringUtils.isNotEmpty(uploadMsg)){
				uploadMsg="本次上传检测到以下内容： <br/> "+uploadMsg;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 上传录波文件 由于这个方法是多线程调用uploadedFileList使用线程安全的集合
	 * @param event
	 */
	public void handleWaveFileUpload(FileUploadEvent event) {
		UploadedFile uf = event.getFile();
		String fileName = uf.getFileName();
		String extName = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
		if(FILE_FORMAT_CFG.equals(extName)){
			updateUploadMsg(uf);
		}
		uploadFileMap.put(fileName, uf.getContents());
		//验证是否上传了文件名相同的cfg和dat文件
		//上传文件
		if (uploadFileMap.size() == 2) {
			if(StringUtils.isNotEmpty(uploadMsg)){
				return ;
			}
			int status = wfam.uploadWaveFile(uploadFileMap, selectedWaveEquipment,faultId);
			if (status == 0) {
				generateWaveFileList();
				addSuccessMessage(fileName + "上传成功");
			} else if (status == -1) {
				addErrorMessage("上传文件列表存在异常");
			}else if (status == 1) {
				addErrorMessage("发生IO异常请联系管理员，谢谢");
			}else {
				addErrorMessage("发生未知异常");
			}
			uploadFileMap.clear();
		}else {
			String otherFormat = FILE_FORMAT_CFG.equals(extName)?FILE_FORMAT_DAT:FILE_FORMAT_CFG;
			FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_WARN,"等待"+otherFormat+"文件上传", null);
			FacesContext.getCurrentInstance().addMessage("提示", facesMsg);
		}
	}

	/**
	 * 取消录波文件的上传
	 */
	public void cancleUpload(){
		uploadFileMap.clear();
		uploadMsg="";
		addSuccessMessage("文件上传已取消");
	}

	/**
	 * 继续上传录波文件
	 */
	public void reUploadFile(){
		if(uploadFileMap.size()!=2){
			return ;
		}
		String fileName = uploadFileMap.keySet().iterator().next();
		String noExtName = fileName.substring(0, fileName.lastIndexOf("."));
		int status = wfam.uploadWaveFile(uploadFileMap, selectedWaveEquipment,faultId);
		if (status == 0) {
			generateWaveFileList();
			fspm.ayncUpdateWaveUploadInfo(faultId, selectedWaveEquipment.getId(), fileName);
			addSuccessMessage(noExtName + "上传成功");
		} else if (status == -1) {
			addErrorMessage("上传文件列表存在异常");
		}else if (status == 1) {
			addErrorMessage("发生IO异常请联系管理员，谢谢");
		}else {
			addErrorMessage("发生未知异常");
		}
		uploadFileMap.clear();
		uploadMsg="";
	}

	public void onWaveEquipmentRowSelect(SelectEvent event) {
		selectedWaveEquipment = (Equipment) event.getObject();
		uploadMsg="";
	}

	public void onWaveEquipmentRowUnSelect(UnselectEvent event) {
		selectedWaveEquipment = null;
		uploadMsg="";
	}

	/**
	 * 下载整个故障的录波文件
	 */
	public void prepareDownloadFile() {
		prepareDownloadFile(null);
	}
	/**
	 * 下载单个变电站的录波文件
	 */
	public void prepareDownloadFile(String stationId) {
		if (StringUtils.isEmpty(fault.getEquipment_id()) || StringUtils.isEmpty(fault.getEtype())) {
			addErrorMessage("查找文件失败，无法下载");
			return;
		}
		FileInputStream fis = null;
		try {
			fis = wfam.generateDownloadZipFile(fault, stationId);
			downloadFile = new DefaultStreamedContent(fis, "application/octet-stream", stationId + ".zip") ;
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		} 
		if(downloadFile == null) {
			addErrorMessage("查找文件失败，无法下载");
		}
	}

	public String getWaveEquipmentType(Equipment e) {
		if(e instanceof WaveEquipment) {
			return "集中录波";
		}else if(e instanceof ProtectionEquipment) {
			return ((ProtectionEquipment) e).getType();
		}
		return "";
	}

	public List<AbstractWaveFile> getWaveFileByStationId(String stationId){
		List<AbstractWaveFile> result=new ArrayList<AbstractWaveFile>();
		if(StringUtils.isNotEmpty(stationId)){
			return waveFiles.get(stationId);
		}
		if(null!=fault){
			if(StringUtils.isNotEmpty(fault.getStationId())){
				result.addAll(waveFiles.get(fault.getStationId()));
			}
			if(StringUtils.isNotEmpty(fault.getStationId2())){
				result.addAll(waveFiles.get(fault.getStationId2()));
			}
		}
		return result;
	}

	public List<Equipment> getWaveEquipmentsByStationId(String stationId){
		return waveEquipments.get(stationId);
	}

	public Equipment getSelectedWaveEquipment() {
		return selectedWaveEquipment;
	}

	public void setSelectedWaveEquipment(Equipment selectedWaveEquipment) {
		this.selectedWaveEquipment = selectedWaveEquipment;
	}

	public StreamedContent getDownloadFile() {
		return downloadFile;
	}

	public void setDownloadFile(StreamedContent downloadFile) {
		this.downloadFile = downloadFile;
	}

	public boolean isShowRelatedEquipment() {
		return showRelatedEquipment;
	}

	public void setShowRelatedEquipment(boolean showRelatedEquipment) {
		this.showRelatedEquipment = showRelatedEquipment;
	}

	public String getUploadMsg() {
		return uploadMsg;
	}

	public void setUploadMsg(String uploadMsg) {
		this.uploadMsg = uploadMsg;
	}

}
